import sys

class BaseHandler(object):
    def __init__(self, factory, widget):
        self.parent    = None      #
        self.factory   = factory   #
        self.widget    = widget    # concrete widget
        self.packed    = False     #
        self.wid       = None      # not available yet
        self.models    = set()
        self.variables = {}

    def setParent(self, parent):
        self.parent = parent

    def getParent(self):
        return self.parent

    def initialize(self, wid, attributes):
        pass

    def addModel(self, model):
        self.models.add(model)

    def setAttribute(self, attr, value):
        try:
            self.widget[attr] = value
        except:
            print "error: bad attribute! (%s=%s)" % (attr, value)

    def setValue(self, value = None, row = -1, column = -1):
        raise "error: setValue - requires concrete implementation by derived class!"

    def getValue(self, row = -1, column = -1):
        raise "error: getValue - requires concrete implementation by derived class!"

    ## trying to select something
    def select(self, row = -1, column = -1):
        raise "error: select - requires concrete implementation by derived class!"

    ## trying to deselect something
    def deselect(self, row = -1, column = -1):
        raise "error: deselect - requires concrete implementation by derived class!"

    ## removing content (concrete implementation depends on widget)
    #  @param  row    [in] clearing a row    (-1: all rows).
    #  @param  column [in] clearing a column (-1: all columns).
    #  @return none.
    def clear(self, row = -1, column = -1):
        raise "error: clear - requires concrete implementation by derived class!"



class BaseModel(object):
    def __init__(self):
        self.factory = None

    def initialize(self):
        pass

    def quit(self):
        try:
            self.factory.controller.parent.quit()
        except:
            print "failed to quit application!"

    def setFactory(self, factory):
        self.factory = factory

    ## this is intented for accessing a widget by the model.
    def setAttribute(self, wid, attr, value):
        if not self.factory == None:
            try:
                handler = self.factory.handler[wid]
                handler.setAttribute(attr, value)
            except:
                pass

    ## this is intented for clearing content of given widget
    def clear(self, wid, row = -1, column = -1):
        if not self.factory == None:
            try:
                handler = self.factory.handler[wid]
                handler.clear(row, column)
            except:
                pass # FIXME: needs log output
        else:
            pass # FIXME: needs log output

    ## this is intented for accessing a widget by the model.
    def setValue(self, wid, value = None, row = -1, column = -1):
        if not self.factory == None:
            try:
                handler = self.factory.handler[wid]
                handler.setValue(value, row, column)
            except:
                pass # FIXME: needs log output
        else:
            pass # FIXME: needs log output

    ## this is intented for accessing a widget by the model.
    def getValue(self, wid, row = -1, column = -1):
        if not self.factory == None:
            try:
                handler = self.factory.handler[wid]
                return handler.getValue(row, column)
            except:
                print "BaseModel: getValue - failed to find handle for wid '%s'" % (wid)
        return None

    def addValue(self, wid, value):
        if not self.factory == None:
            try:
                handler = self.factory.handler[wid]
                handler.addValue(value)
            except:
                print "Unexpected error:", sys.exc_info()[0]

    def removeValue(self, wid, value):
        if not self.factory == None:
            try:
                handler = self.factory.handler[wid]
                handler.removeValue(value)
            except:
                print "BaseModel: removeValue - failed to find handle for wid '%s'" % (wid)

    ## this is intended as notification for the model implementation by the GUI (user)
    #  a value has changed, a button has been clicked, ...
    def updateValue(self, wid, value, mode):
        pass

    ## trying to select something
    def select(self, wid, row = -1, column = -1):
        if not self.factory == None:
            try:
                handler = self.factory.handler[wid]
                handler.select(row, column)
            except:
                print "BaseModel: select - failed to find handle for wid '%s'" % (wid)

    def event(self, wid, evid):
        pass

    def getText(self, id):
        return self.factory.controller.getText(id)
